home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
misc
/
amag
/
9301b.lha
/
Devices (Folge 3)
/
Terminal0.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-18
|
11KB
|
398 lines
/* Terminal0.c
Autor: E.G. Meyzis, Mai 1992
Compile Instr. fuer DICE: execute cterm0
dcc Terminal0.c -c -o t:Terminal0.o
Link Instr. fuer DICE: execute lterm0
dlink dlib:c.o t:Terminal0.o dlib:c.lib+
dlib:amigas20.lib dlib:auto.lib dlib:x.o -o Terminal0
*/
#include <Devices/Serial.h>
#include <Dos/Dos.h>
#include <Dos/DosExtens.h>
#include <Exec/Exec.h>
#include <Intuition/Intuition.h>
#include <stdlib.h>
#include <stdio.h>
/* +++++++++ Definitionen ++++++++++++
*/
#define TRUE 1 /* um mit dem Datentyp BOOL zu arbeiten */
#define FALSE 0
/* zwei Definitionen fuer DOS-Fenster */
#define TxTitle "CON:0/0/500/100/ Terminal-Send "
#define RxTitle "CON:0/101/500/100/ Terminal-Receive "
/* Texte zur Info bei Text-Senden/Empfangen */
#define Senden "\nSende Textdatei\n\n"
#define Empfang "\nwarte auf Textdatei\n\n"
#define Beendet "\nÜbertragung beendet\n\n"
#define Unit0 0 /* eingebaute ser. Schnittstelle */
#define PLaenge 512 /* Pufferlaenge Datemuebertrag. */
struct GetBlock /* nur in GetWinPtr verwendet */
{
struct StandardPacket stdPkt;
struct InfoData info;
};
/* +++++++++ Datentypen ++++++++++++
*/
typedef char BOOL;
typedef char *CharPtr;
typedef struct IOExtSer *IOExtSerPtr;
typedef struct FileHandle *FileHandleBPtr; /* BPTR */
typedef struct FileHandle *FileHandlePtr; /* Adresse */
typedef struct Window *WindowPtr;
typedef struct GetBlock *GetBlockPtr;
typedef struct MessagePort *MsgPortPtr;
typedef struct IntuiMessage *IntuiMessagePtr;
APTR GetSysBase(); /* Adr ExecBase aus Adresse 4 holen */
void GetWinPointer (FileHandleBPtr *winHdl,
WindowPtr *winPtr);
void MakeWindow(CharPtr namePtr,
WindowPtr *winPtr,
FileHandleBPtr *fileHdl);
BOOL WindowsAngelegt();
void SetBaudRate(IOExtSerPtr serPtr);
BOOL InitSerialDev(IOExtSerPtr serPtr, int cmnd);
BOOL SerialVorbereitet();
void SetTermChars(IOExtSerPtr serPtr);
void FlushSerialDevice();
void SendeTextDatei(IOExtSerPtr txReqPtr);
void EmpfangeTextDatei(IOExtSerPtr rxReqPtr);
void TerminalLoop();
void Aufraeumen();
/* +++++++++ globale Variablen ++++++++++++
*/
struct ExecBase *execBasePtr;
/*
Doppelt ausgelegte Datenstrukturen
Sendeteil: Empfangsteil:
*/
/* Device zweimal oeffnen */
struct IOExtSer txRequest, rxRequest;
/* jedem Device seinen Puffer */
char rxPuffer[PLaenge], txPuffer[PLaenge];
/* getrennte Fenster fuer Ein-/Ausgaben */
FileHandleBPtr txWin, rxWin;
WindowPtr txWinPtr, rxWinPtr;
APTR GetSysBase() /* Adr ExecBase aus Adresse 4 holen */
{
long *systemBasis;
systemBasis = (APTR)4;
return (APTR)*systemBasis;
}
/* Mit Dos.Open geoeffnete Fenster liefern nur einen Handle
und leider nicht den WindowPtr; deshalb:
*/
void GetWinPointer (FileHandleBPtr *winHdl,
WindowPtr *winPtr)
{
MsgPortPtr portPtr;
GetBlockPtr pktPtr;
FileHandlePtr wHdlPtr;
*winPtr = NULL; /* negatives Vorurteil */
if (IsInteractive(*winHdl)) /* Fenster vorhanden? */
{
wHdlPtr = (APTR)((long)*winHdl) << 2; /* BPTR -> Adr */
if (portPtr = (MsgPortPtr)CreateMsgPort())
{
/* Speicher fuer Dos.Packet anfordern*/
pktPtr=(GetBlockPtr)AllocMem(sizeof(struct GetBlock),
MEMF_CLEAR|MEMF_PUBLIC);
if (pktPtr) /* Dos.Packet initialisieren */
{
pktPtr->stdPkt.sp_Pkt.dp_Link =
&pktPtr->stdPkt.sp_Msg;
pktPtr->stdPkt.sp_Pkt.dp_Port = portPtr;
pktPtr->stdPkt.sp_Pkt.dp_Type = ACTION_DISK_INFO;
pktPtr->stdPkt.sp_Pkt.dp_Arg1 = &pktPtr->info >>2;
pktPtr->stdPkt.sp_Msg.mn_Node.ln_Name =
&pktPtr->stdPkt.sp_Pkt;
pktPtr->stdPkt.sp_Msg.mn_Node.ln_Type= NT_MESSAGE;
pktPtr->stdPkt.sp_Msg.mn_Length =
sizeof(struct Message);
PutMsg(wHdlPtr->fh_Type, pktPtr);/*und absenden */
do
WaitPort(portPtr); /* auf Antwort von Dos */
while (APTR)GetMsg(portPtr) != pktPtr;
if (pktPtr->stdPkt.sp_Pkt.dp_Res1)/* Antwort ok */
*winPtr = (APTR)pktPtr->info.id_VolumeNode;
DeleteMsgPort(portPtr);
FreeMem(pktPtr, sizeof(struct GetBlock));
}
else
DeleteMsgPort(portPtr);
}
} /* Interactive */
}
/* Dos.Fenster anlegen und WindowPtr holen */
void MakeWindow(CharPtr namePtr,
WindowPtr *winPtr,
FileHandleBPtr *fileHdl)
{
*fileHdl = (FileHandleBPtr)Open(namePtr, MODE_NEWFILE);
if (*fileHdl)
GetWinPointer(&(*fileHdl), &(*winPtr));
}
/* Beide Terminal-Fenster anlegen und bei Fehlschlag
Ressourcen freigeben.
*/
BOOL WindowsAngelegt()
{
BOOL angelegt;
angelegt = FALSE; /* zunaechst keines vorhanden */
MakeWindow(TxTitle, &txWinPtr, &txWin);/* Sende-Fenster */
if (txWinPtr)
{
angelegt = TRUE;
/* um Tastatureingaben durch Intuition abzufangen */
ModifyIDCMP(txWinPtr, IDCMP_RAWKEY|IDCMP_VANILLAKEY);
MakeWindow(RxTitle, &rxWinPtr, &rxWin);/*Empf.-Fenst */
if (rxWinPtr = NULL)
{
angelegt = FALSE; /* Sendefenster aufgeben */
Close(txWin);
txWin = NULL;
}
}
else /* WindowPtr nicht zu ermitteln */
if (txWin)
Close(txWin); /* deshalb schliessen */
return angelegt;
}
/* 3. Erweiterung Listing 3-3 hier einsetzen */
/* 4. Erweiterung Listing 3-4 hier einbauen */
/* Device-Struktur initialisieren und Device oeffnen */
BOOL InitSerialDev(IOExtSerPtr serPtr, int cmnd)
{
MsgPortPtr portPtr;
BOOL erfolg;
erfolg = FALSE;
portPtr = (MsgPortPtr)CreateMsgPort(); /* fuer Device */
if (portPtr)
{
serPtr->io_SerFlags = SERF_SHARED; /* Mehrfachutzung */
serPtr->IOSer.io_Length = 1;/* 1 Byte lesen/schreib. */
serPtr->IOSer.io_Message.mn_ReplyPort = portPtr;
OpenDevice(SERIALNAME, Unit0, serPtr, 0);
if (serPtr->IOSer.io_Error != IOERR_OPENFAIL)
{
erfolg = TRUE;
/* 3. Erweiterung Listing 3-3 hier aufrufen
SetBaudRate(serPtr);
*/
serPtr->IOSer.io_Command = cmnd;/* CMD_WRITE/READ */
}
else /* Device nicht zu oeffnen */
{
DeleteMsgPort
(serPtr->IOSer.io_Message.mn_ReplyPort);
serPtr->IOSer.io_Message.mn_ReplyPort = NULL;
}
}
return erfolg;
}
BOOL SerialVorbereitet() /* getrennte Devices als Sende- */
{ /* Empfangskanal oeffnen */
BOOL vorbereitet;
if (InitSerialDev(&txRequest, CMD_WRITE)) /* Sendekanal */
{
vorbereitet = TRUE;
txRequest.IOSer.io_Data=txPuffer;/*f. Dateiuebertrag.*/
if (InitSerialDev(&rxRequest, CMD_READ))/*Empf.-Kanal*/
{
rxRequest.IOSer.io_Data = rxPuffer; /* ext. Puffer*/
}
else /* kein Empfangskanal zu oeffnen */
{
vorbereitet = FALSE;
DeleteMsgPort
(txRequest.IOSer.io_Message.mn_ReplyPort);
txRequest.IOSer.io_Message.mn_ReplyPort = NULL;
}
}
else/*kein Kanal zu oeffnen; Device evtl exklusiv belegt*/
vorbereitet = FALSE;
return vorbereitet;
}
/* 5. Erweiterung Listing 3-5 hier einbauen */
/* 6. Erweiterung Listing 3-6 hier einbauen */
/* 6. Erweiterung Listing 3-6 */
void TerminalLoop() /* Hauptschleife des Prog. */
{
IntuiMessagePtr inMsgPtr; /* fuer IDCMP-Nachr. aus dem */
long klasse, /* Sendefenster */
done,
txSig, /*aus UserPort des Sendefensters */
rxSig, /* aus Empfangs-Device-Struktur */
erwartSig, /* Kombination txSig | rxSig */
erhaltSig; /* angekommene Signale */
int raw; /* fuer Tastatur-Codes */
txSig = 1 << txWinPtr->UserPort->mp_SigBit;
rxSig = 1 <<
rxRequest.IOSer.io_Message.mn_ReplyPort->mp_SigBit;
erwartSig = txSig | rxSig;
SendIO(&(rxRequest)); /* async. aufs 1. Zeichen warten */
for(;;)
{
erhaltSig = Wait(erwartSig); /* Tastendruck/Empfang */
if (txSig & erhaltSig) /*Taste im Sendefenster gedr. */
{
inMsgPtr = (IntuiMessagePtr) /* Msg. abholen */
GetMsg(txWinPtr->UserPort);
klasse = inMsgPtr->Class; /* copy Msg teilweise */
raw = inMsgPtr->Code;
ReplyMsg(inMsgPtr); /* Msg beantworten */
if (IDCMP_VANILLAKEY & klasse) /* ASCII-Zeichen */
{
txPuffer[0] = raw; /* Zeichen in Sende-Puffer */
if (txPuffer[0] != 033) /* nicht ESC gedrueckt */
{
done = Write(txWin, txPuffer, 1); /* Echo */
DoIO(&txRequest); /* Zeichen senden */
}
else /* ESC gedrueckt */
break; /* Programm abbrechen */
}
else
if (IDCMP_RAWKEY & klasse) /* z.B. F1 - F10 gedr.*/
{
if ((raw >= 80) && (raw <= 89))
{
/* Funktionstasten auswerten F1 - F10 */
if (raw == 80)
{ /* F1 */
/* 5. Erweiterung
Aufruf SendeTextDatei(txRequest);
aus Listing 3-5 hier einfuegen
*/
}
else
if (raw == 81) /* F2 */
{
/* 6. Erweiterung
Aufruf EmpfangeTextDatei(rxRequest);
aus Listing 3-6 hier einfuegen
*/
}
} /* raw >= 80*/
} /* IDCMP_RAWKEY */
} /* txSig */
if (rxSig & erhaltSig)/* mind. 1 Zeich. im Empf-kanal*/
{
WaitIO(&rxRequest); /* dieses abholen */
if (rxRequest.IOSer.io_Error == 0)
done = Write(rxWin, rxPuffer, 1);/*u. ausgeben */
/* 2. Erweiterung gem Listing 3-2 hier einfuegen */
SendIO(&rxRequest); /* aufs naechste Zeich. wart. */
}
} /* for */
AbortIO(&rxRequest); /* Auftrag an Device abbrechen */
WaitIO(&rxRequest);
}
/* 1. Erweiterung FlushSerialDevice;
Listing 3-1 hier einbauen
*/
void Aufraeumen()
{
DeleteMsgPort(rxRequest.IOSer.io_Message.mn_ReplyPort);
CloseDevice(&rxRequest);
DeleteMsgPort(txRequest.IOSer.io_Message.mn_ReplyPort);
CloseDevice(&txRequest);
Close(rxWin);
Close(txWin);
/* 1. Erweiterung
Aufruf FlushSerialDevice aus
Listing 3-1 hier vornehmen
*/
}
int main()
{
BOOL done;
execBasePtr = GetSysBase(); /* Adr ExecBase beschaffen */
if (execBasePtr->LibNode.lib_Version >= 36) /* ja, OS 2 */
{
if (WindowsAngelegt() && SerialVorbereitet())
{
TerminalLoop(); /* Steuerschleife des Programms */
Aufraeumen();
}
}
return 0;
}